home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks97
/
FinderDungeon.sit
/
Finder Dungeon
/
source code
/
ScriptableFinder.c
< prev
next >
Wrap
Text File
|
1997-06-28
|
32KB
|
764 lines
// File by Leonard Rosenthol
#include <icons.h>
#include <AppleEvents.h>
#include <AERegistry.h>
#include "FinderRegistry.h"
#include "ScriptableFinder.h"
OSErr convertfahtoAElist(FSSpecArrayHandle fah, AEDescList *selectionlist)
/* A routine to convert the data contained within the passed FSSpecArrayHandle into an AEDescList
which can be passed as a parameter inside an Apple Event.
Input: fah - source FSSpecArrayHandle.
Input: *selectionlist - result AEDescList (must be pre-created) passed by reference.
Output: error code that occured. */
{
short result;
result = noErr;
if (fah != nil)
{
short i, maxfah, count;
count = 0;
maxfah = (GetHandleSize((Handle)fah) / sizeof(FSSpec));
for (i = 0; i < maxfah; i++)
if (result == noErr)
{
count++;
if ((result = AEPutPtr(selectionlist, count, typeFSS, &(*fah)[i], sizeof(FSSpec))) != noErr)
count--;
}
}
return(result);
}
OSErr AddToFSSpecArrayHandle (FSSpec *f, FSSpecArrayHandle fah)
{
OSErr result;
long l;
l = InlineGetHandleSize((Handle)fah);
SetHandleSize((Handle)fah, l + sizeof(FSSpec));
result = MemError();
if (result == noErr)
BlockMoveData(f, (Ptr)((long)*fah + l), sizeof(FSSpec));
return(result);
}
OSErr GetFinderProcess (ProcessSerialNumber *finderpsn, Boolean shortcut)
/* A routine to determine the process serial number of the Finder. It returns the result as a
parameter passed by reference. It also has a Boolean parameter which specifies whether or not
the returned process serial number will represent the Finder process serial number as
"kCurrentProcess" if it is the current process to allow a shortcut of the _GetNextEvent call
dependencies of processing an AppleEvent.
Input: shortcut - allow "kCurrentProcess" to be used if we are in the current process.
Input: *finderpsn - result ProcessSerialNumber passed by reference.
Output: error code that occured. */
{
Boolean result;
ProcessSerialNumber psn, currentpsn;
ProcessInfoRec pir;
psn.highLongOfPSN = 0;
psn.lowLongOfPSN = kNoProcess;
pir.processInfoLength = sizeof(ProcessInfoRec);
pir.processName = nil; // don't want these bits of information
pir.processAppSpec = nil;
while (GetNextProcess(&psn) == noErr)
if (GetProcessInformation(&psn, &pir) == noErr)
if ((pir.processType == kFinderType) && (pir.processSignature == kFinderSignature))
{
if (shortcut && (GetCurrentProcess(¤tpsn) == noErr) &&
(SameProcess(¤tpsn, &psn, &result) == noErr) && result)
{ // use the current process to shortcut the event dispatching
finderpsn->highLongOfPSN = 0;
finderpsn->lowLongOfPSN = kCurrentProcess;
}
else
*finderpsn = psn; // found the Finder's psn
return(noErr); // got the process serial number
}
return(procNotFound); // got an error - not found
}
Boolean IsRelativeProcessSerialNumber (ProcessSerialNumber *psn)
/* A simple routine which determines whether the process serial number given is a relative one.
This means that it isn't a number which refers to the process outright but rather refers to the
process because it's current.
Input: psn - the ProcessSerialNumber to check.
Output: Boolean result. */
{
return((psn->highLongOfPSN == 0) && (psn->lowLongOfPSN == kCurrentProcess));
}
OSErr GetScriptableFinderSelection (FSSpecArrayHandle *fah, Boolean usesystemmode)
/* A routine to get the Finder's selection using the GetData Apple Event. It tries it's best to get
the result immediately and resorts to allowing the shortcut in the AESend routine where the
event is sent to the current process specified by "kCurrentProcess" in the ProcessSerialNumber.
Input: *fah - result FSSpecArrayHandle passed by reference. Nil if no items selected.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
OSType selectiondescriptor, resultdescriptor;
ProcessSerialNumber targetpsn;
AEDesc targetaddress, selectiondesc, nulldesc, directdesc, requestdesc, listdesc;
AppleEvent myae, myreply;
*fah = nil; // make sure we have a valid empty result
selectiondescriptor = pSelection;
resultdescriptor = typeFSS;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
/* Here's a good problem. If we shortcut the Apple Event processing mechanism by using the relative
kCurrentProcess in the process serial number to get to the Finder's 'Get Data' routine this
works fine if the A5 register is that of the Finder. However, Magic Menu calls this routine from
a patch within _MenuKey or _MenuSelect and the Process Manager patches over these routines. It
puts its own A5 in but doesn't modify the low-memory global. So... just to be sure that we've
got the correct A5 we'll restore the A5 world if we're using the relative process serial number.
Otherwise the Apple Event is sent via the Event Manager and the A5 register will be correct. */
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
/* The following if statement is the guts of the GetScriptableFinderSelection routine. It
composes the AppleEvent and fills in all the correct parameters and options. Then it calls
the Finder to get the information and extracts the returned data from the descriptor list.
It puts the items in an FSSpecArrayHandle. If an error occurs it just returns nil. Note that
this routine uses an assignment followed by a comparison which although not good logic allows
this routine to be compressed into a single if statement linked with terminating and comparisons
whilst collecting the error number that occurred. */
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kAECoreSuite, kAEGetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateDesc(typeType, &selectiondescriptor, sizeof(selectiondescriptor), &selectiondesc)) == noErr) &&
((errnum = AECreateDesc(typeNull, nil, 0, &nulldesc)) == noErr) &&
((errnum = CreateObjSpecifier(cProperty, &nulldesc, formPropertyID, &selectiondesc, TRUE, &directdesc)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) &&
((errnum = AEDisposeDesc(&selectiondesc)) == noErr) &&
((errnum = AEDisposeDesc(&nulldesc)) == noErr) &&
((errnum = AEDisposeDesc(&directdesc)) == noErr) &&
((errnum = AECreateDesc(typeType, &resultdescriptor, sizeof(resultdescriptor), &selectiondesc)) == noErr) &&
((errnum = AECoerceDesc(&selectiondesc, typeAEList, &requestdesc)) == noErr) &&
((errnum = AEDisposeDesc(&selectiondesc)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyAERequestedType, &requestdesc)) == noErr) &&
((errnum = AEDisposeDesc(&requestdesc)) == noErr) &&
((errnum = AESend(&myae, &myreply, kAEWaitReply, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEGetParamDesc(&myreply, keyAEResult, typeAEList, &listdesc)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr) &&
((errnum = AEDisposeDesc(&myae)) == noErr))
{ // Whew! We passed the test. Do we get a cookie now?
short i;
long count;
AEKeyword returnedkeyword;
AEDesc resultdesc;
// Convert result AEDesc list of FSSpecs to our own internal FSSpecArrayHandle
*fah = (FSSpecArrayHandle)NewHandle(0);
if ((errnum = AECountItems(&listdesc, &count)) == noErr)
for (i = 1; i <= count; i++)
if ((errnum == noErr) && (errnum = AEGetNthDesc(&listdesc, i, typeFSS, &returnedkeyword, &resultdesc)) == noErr)
{
HLock(resultdesc.dataHandle);
errnum = AddToFSSpecArrayHandle(*(FSSpecHandle)resultdesc.dataHandle, *fah);
HUnlock(resultdesc.dataHandle);
if (errnum == noErr)
errnum = AEDisposeDesc(&resultdesc);
}
if (errnum == noErr)
errnum = AEDisposeDesc(&listdesc);
}
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr SetScriptableFinderSelection (FSSpecArrayHandle fah, Boolean usesystemmode,
AESendMode sendmode)
/* A routine to set the Finder's selection using the GetData Apple Event. It tries it's best to get
the result immediately and resorts to allowing the shortcut in the AESend routine where the
event is sent to the current process specified by "kCurrentProcess" in the ProcessSerialNumber.
Input: fah - FSSpecArrayHandle which contains the items to select. Nil if no selection.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
OSType selectiondescriptor, resultdescriptor;
ProcessSerialNumber targetpsn;
AEDesc targetaddress, selectiondesc, nulldesc, directdesc;
AEDescList selectionlist;
AppleEvent myae, myreply;
selectiondescriptor = pSelection;
resultdescriptor = typeFSS;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kAECoreSuite, kAESetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateDesc(typeType, &selectiondescriptor, sizeof(selectiondescriptor), &selectiondesc)) == noErr) &&
((errnum = AECreateDesc(typeNull, nil, 0, &nulldesc)) == noErr) &&
((errnum = CreateObjSpecifier(cProperty, &nulldesc, formPropertyID, &selectiondesc, TRUE, &directdesc)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) &&
((errnum = AEDisposeDesc(&selectiondesc)) == noErr) &&
((errnum = AEDisposeDesc(&nulldesc)) == noErr) &&
((errnum = AEDisposeDesc(&directdesc)) == noErr) &&
((errnum = AECreateList(nil, 0, FALSE, &selectionlist)) == noErr) &&
((errnum = convertfahtoAElist(fah, &selectionlist)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyAEData, &selectionlist)) == noErr) &&
((errnum = AEDisposeDesc(&selectionlist)) == noErr) &&
((errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr))
errnum = AEDisposeDesc(&myae);
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr RevealScriptableFinderSelection (FSSpecArrayHandle fah, Boolean usesystemmode,
AESendMode sendmode)
/* A routine to reveal the contents of a given FSSpecArrayHandle using the new kAEMakeObjectVisible
Apple Event understood by the scriptable Finder. This event is better than the old 'reveal'
event as the old event doesn't deselect any previously selected items (and therefore is to be
considered buggy).
Input: fah - FSSpecArrayHandle which contains the items to reveal. Nil if nothing to reveal.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
ProcessSerialNumber targetpsn;
AEDesc targetaddress;
AEDescList selectionlist;
AppleEvent myae, myreply;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kAEMiscStandards, kAEMakeObjectsVisible, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateList(nil, 0, FALSE, &selectionlist)) == noErr) &&
((errnum = convertfahtoAElist(fah, &selectionlist)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &selectionlist)) == noErr) &&
((errnum = AEDisposeDesc(&selectionlist)) == noErr) &&
((errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr))
errnum = AEDisposeDesc(&myae);
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr OpenScriptableFinderSelection (FSSpecArrayHandle fah, Boolean usesystemmode,
AESendMode sendmode, FSSpec *usingf)
/* A routine to open the items in a given FSSpecArrayHandle using the specified FSSpec.
Input: fah - FSSpecArrayHandle which contains the items to open. Nil if nothing to open.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Input: *usingf - the optional FSSpec which is designated to open the items.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
ProcessSerialNumber targetpsn;
AEDesc targetaddress;
AEDescList selectionlist;
AppleEvent myae, myreply;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateList(nil, 0, FALSE, &selectionlist)) == noErr) &&
((errnum = convertfahtoAElist(fah, &selectionlist)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &selectionlist)) == noErr) &&
((errnum = AEDisposeDesc(&selectionlist)) == noErr))
{
if (usingf != nil)
{ // add the using parameter
AEDesc usingdesc;
if (((errnum = AECreateDesc(typeFSS, usingf, sizeof(FSSpec), &usingdesc)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyAEUsing, &usingdesc)) == noErr))
errnum = AEDisposeDesc(&usingdesc);
}
if ((errnum == noErr) &&
((errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr))
errnum = AEDisposeDesc(&myae);
}
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr PrintScriptableFinderSelection (FSSpecArrayHandle fah, Boolean usesystemmode,
AESendMode sendmode)
/* A routine to print the items in a given FSSpecArrayHandle.
Input: fah - FSSpecArrayHandle which contains the items to open. Nil if nothing to open.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
ProcessSerialNumber targetpsn;
AEDesc targetaddress;
AEDescList selectionlist;
AppleEvent myae, myreply;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kCoreEventClass, kAEPrintDocuments, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateList(nil, 0, FALSE, &selectionlist)) == noErr) &&
((errnum = convertfahtoAElist(fah, &selectionlist)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &selectionlist)) == noErr) &&
((errnum = AEDisposeDesc(&selectionlist)) == noErr) &&
((errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr))
errnum = AEDisposeDesc(&myae);
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr UpdateScriptableFinderContainer (FSSpec *f, Boolean usesystemmode, AESendMode sendmode)
/* A routine to update the contents of a Finder window immediately. The Finder normally updates
any changes it discovers in modification date of a folder by scanning every 5-10 seconds in idle
time. Sometimes this delay can be somewhat disconcerting for a Macintosh user who expects an
icon to appear instantly. To circumvent this you should send the Finder an update event
specifying which container to update.
Input: *f - The FSSpec of the folder to be updated.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
ProcessSerialNumber targetpsn;
AEDesc targetaddress, updatedesc;
AppleEvent myae, myreply;
if (GetFinderProcess(&targetpsn, kRelativeFinderPSN) == noErr)
{
// if (usesystemmode)
// TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5)
saveA5 = SetCurrentA5();
if (((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) &&
((errnum = AECreateAppleEvent(kAEFinderSuite, kAEUpdate, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) &&
((errnum = AEDisposeDesc(&targetaddress)) == noErr) &&
((errnum = AECreateDesc(typeFSS, f, sizeof(FSSpec), &updatedesc)) == noErr) &&
((errnum = AEPutParamDesc(&myae, keyDirectObject, &updatedesc)) == noErr) &&
((errnum = AEDisposeDesc(&updatedesc)) == noErr) &&
((errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil)) == noErr) &&
((errnum = AEDisposeDesc(&myreply)) == noErr))
errnum = AEDisposeDesc(&myae);
if (fiddlewithA5)
SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode)
// TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
static pascal OSErr addIconsToAERecord (ResType theType, Handle *theIcon, void *yourDataPtr)
{
return(AEPutKeyPtr((AERecord*)yourDataPtr, theType, theType, **theIcon, GetHandleSize(*theIcon)));
}
IconActionUPP iconActionProc = nil;
OSErr SetScriptableFinderFileIcon (FSSpec *f, Handle iconFamily, Boolean usesystemmode,
AESendMode sendmode)
/*
Input: f - FSSpec which contains the item to change the custom icon of.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
OSType icondescriptor;
ProcessSerialNumber targetpsn;
AEDesc targetaddress, propdesc, filedesc, directdesc, icondesc, nulldesc, targetdesc;
AppleEvent myae;
nulldesc.descriptorType = typeNull;
nulldesc.dataHandle = nil;
icondescriptor = pIconBitmap;
if (GetFinderProcess(&targetpsn, kAbsoluteFinderPSN) == noErr)
{
// if (usesystemmode) TurnSystemModeOn(); // you really DON'T want to do this
// create the icon family descriptor
{
OSErr err;
if ((err = AECreateList(nil, 0, true, &icondesc)) == noErr) {
if(!iconActionProc)
iconActionProc = NewIconActionProc(addIconsToAERecord);
err = ForEachIconDo(iconFamily, svAllAvailableData, iconActionProc, (void *)&icondesc);
err = AECoerceDesc(&icondesc, cIconFamily, &icondesc);
}
}
if ((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) {
if ((errnum = AECreateAppleEvent(kAECoreSuite, kAESetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) {
if ((errnum = AECreateDesc(typeType, &icondescriptor, sizeof(DescType), &propdesc)) == noErr) {
AliasHandle targetAlias;
NewAlias(nil, f, &targetAlias);
HLock((Handle)targetAlias);
if ((errnum = AECreateDesc(typeAlias, *targetAlias, GetHandleSize((Handle)targetAlias), &filedesc)) == noErr) {
if ((errnum = CreateObjSpecifier(typeWildCard, &nulldesc, typeAlias,&filedesc, TRUE, &targetdesc)) == noErr) {
if ((errnum = CreateObjSpecifier(cProperty, &targetdesc, formPropertyID, &propdesc, TRUE, &directdesc)) == noErr) {
if ((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) {
if ((errnum = AEPutParamDesc(&myae, keyAEData, &icondesc)) == noErr) {
errnum = AESend(&myae, nil, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil);
}
}
AEDisposeDesc(&directdesc);
}
}
AEDisposeDesc(&filedesc);
}
HUnlock((Handle)targetAlias);
AEDisposeDesc(&propdesc);
}
AEDisposeDesc(&myae);
}
AEDisposeDesc(&targetaddress);
}
AEDisposeDesc(&icondesc);
// if (usesystemmode) TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr GetScriptableFinderFileIcon (FSSpec *f, Boolean usesystemmode, AESendMode sendmode, Handle *iconFamily)
/*
Input: f - FSSpec which contains the item to change the custom icon of.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
OSType icondescriptor;
ProcessSerialNumber targetpsn;
AEDesc targetaddress, propdesc, filedesc, directdesc, icondesc, nulldesc, targetdesc;
AppleEvent myae, myreply;
nulldesc.descriptorType = typeNull;
nulldesc.dataHandle = nil;
icondescriptor = pIconBitmap;
if (GetFinderProcess(&targetpsn, kAbsoluteFinderPSN) == noErr)
{
// if (usesystemmode) TurnSystemModeOn(); // you really DON'T want to do this
if ((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(targetpsn), &targetaddress)) == noErr) {
if ((errnum = AECreateAppleEvent(kAECoreSuite, kAEGetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) {
if ((errnum = AECreateDesc(typeType, &icondescriptor, sizeof(DescType), &propdesc)) == noErr) {
AliasHandle targetAlias;
NewAlias(nil, f, &targetAlias);
HLock((Handle)targetAlias);
if ((errnum = AECreateDesc(typeAlias, *targetAlias, GetHandleSize((Handle)targetAlias), &filedesc)) == noErr) {
if ((errnum = CreateObjSpecifier(typeWildCard, &nulldesc, typeAlias,&filedesc, TRUE, &targetdesc)) == noErr) {
if ((errnum = CreateObjSpecifier(cProperty, &targetdesc, formPropertyID, &propdesc, TRUE, &directdesc)) == noErr) {
if ((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) {
errnum = AESend(&myae, &myreply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil);
if (errnum == noErr) {
if (((errnum = AEGetParamDesc(&myreply, keyAEResult, typeWildCard, &icondesc)) == noErr)) {
errnum = AECoerceDesc(&icondesc, typeAERecord, &icondesc);
{ // copy all the records into our iconfamily
OSErr err;
long i, numItems;
AEKeyword keyWord;
DescType theType;
Size theSize;
if (!NewIconSuite(iconFamily)) {
if (!(err = AECountItems(&icondesc, &numItems))) {
for (i = 1; i <= numItems; i++) {
if (!(err = AEGetNthPtr(&icondesc,i,typeWildCard,&keyWord,&theType,
nil,0L,&theSize))) {
Handle buffer = NewHandle(theSize);
HLock(buffer);
if (!(err = AEGetNthPtr(&icondesc,i,typeWildCard,&keyWord,&theType,
*buffer,GetHandleSize(buffer),&theSize))) {
AddIconToSuite(buffer, *iconFamily, keyWord);
}
// DisposeHandle(buffer);
}
}
}
}
}
AEDisposeDesc(&icondesc);
}
}
}
AEDisposeDesc(&directdesc);
}
}
AEDisposeDesc(&filedesc);
}
HUnlock((Handle)targetAlias);
AEDisposeDesc(&propdesc);
}
AEDisposeDesc(&myae);
}
AEDisposeDesc(&targetaddress);
}
// if (usesystemmode) TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr GetScriptableFinderFileLocation (FSSpec *f, Boolean usesystemmode, AESendMode sendmode,
Boolean sendToSelf, Rect *r)
/*
Input: f - FSSpec which contains the item to the position of.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
OSType icondescriptor, finderSig = 'MACS';
ProcessSerialNumber targetpsn;
AEDesc targetaddress, propdesc, filedesc, directdesc, nulldesc, targetdesc, pointdesc;
AppleEvent myae, myReply;
Rect rect;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
nulldesc.descriptorType = typeNull;
nulldesc.dataHandle = nil;
icondescriptor = pBounds;
if (GetFinderProcess(&targetpsn, sendToSelf) == noErr)
{
// if (usesystemmode) TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5) saveA5 = SetCurrentA5();
if ((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(ProcessSerialNumber), &targetaddress)) == noErr) {
if ((errnum = AECreateAppleEvent(kAECoreSuite, kAEGetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) {
if ((errnum = AECreateDesc(typeType, &icondescriptor, sizeof(DescType), &propdesc)) == noErr) {
AliasHandle targetAlias;
NewAlias(nil, f, &targetAlias);
HLock((Handle)targetAlias);
if ((errnum = AECreateDesc(typeAlias, *targetAlias, GetHandleSize((Handle)targetAlias), &filedesc)) == noErr) {
if ((errnum = CreateObjSpecifier(typeWildCard, &nulldesc, typeAlias,&filedesc, TRUE, &targetdesc)) == noErr) {
if ((errnum = CreateObjSpecifier(cProperty, &targetdesc, formPropertyID, &propdesc, TRUE, &directdesc)) == noErr) {
if ((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) {
errnum = AESend(&myae, &myReply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil);
if ( errnum == noErr) {
// Get Rect
if (((errnum = AEGetParamDesc(&myReply, keyAEResult, cQDRectangle, &pointdesc)) == noErr))
rect = **((Rect **)(pointdesc.dataHandle));
}
}
AEDisposeDesc(&directdesc);
}
}
AEDisposeDesc(&filedesc);
}
HUnlock((Handle)targetAlias);
AEDisposeDesc(&propdesc);
}
AEDisposeDesc(&myae);
}
AEDisposeDesc(&targetaddress);
}
// Get Rect
*r = rect;
if (fiddlewithA5) SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode) TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}
OSErr GetScriptableFinderTrashLocation (Boolean usesystemmode, AESendMode sendmode, Boolean sendToSelf, Rect *r)
/*
Input: f - FSSpec which contains the item to the position of.
Input: usesystemmode - a Boolean which determines whether the system's PPC port will be used.
Input: sendmode - which mode to send the Apple Event to the Finder.
Output: error code that occured. */
{
short errnum;
OSType icondescriptor, trshdescriptor, finderSig = 'MACS';
ProcessSerialNumber targetpsn;
AEDesc targetaddress, propdesc, trshpropdesc, filedesc, directdesc, nulldesc, targetdesc, pointdesc;
AppleEvent myae, myReply;
Rect rect;
Boolean fiddlewithA5; // See below for the usage of the A5 variables
long saveA5;
nulldesc.descriptorType = typeNull;
nulldesc.dataHandle = nil;
icondescriptor = pBounds;
trshdescriptor = 'trsh';
if (GetFinderProcess(&targetpsn, sendToSelf) == noErr)
{
// if (usesystemmode) TurnSystemModeOn(); // you really DON'T want to do this
fiddlewithA5 = IsRelativeProcessSerialNumber(&targetpsn);
if (fiddlewithA5) saveA5 = SetCurrentA5();
if ((errnum = AECreateDesc(typeProcessSerialNumber, &targetpsn, sizeof(ProcessSerialNumber), &targetaddress)) == noErr) {
if ((errnum = AECreateAppleEvent(kAECoreSuite, kAEGetData, &targetaddress, kAutoGenerateReturnID, kAnyTransactionID, &myae)) == noErr) {
if ((errnum = AECreateDesc(typeType, &icondescriptor, sizeof(DescType), &propdesc)) == noErr) {
if ((errnum = AECreateDesc(typeType, &trshdescriptor, sizeof(DescType), &trshpropdesc)) == noErr) {
if ((errnum = CreateObjSpecifier(cProperty, &nulldesc, formPropertyID, &trshpropdesc, TRUE, &targetdesc)) == noErr) {
if ((errnum = CreateObjSpecifier(cProperty, &targetdesc, formPropertyID, &propdesc, TRUE, &directdesc)) == noErr) {
if ((errnum = AEPutParamDesc(&myae, keyDirectObject, &directdesc)) == noErr) {
errnum = AESend(&myae, &myReply, sendmode, kAENeverInteract, kAEDefaultTimeout, nil, nil);
if ( errnum == noErr) {
// Get Rect
if (((errnum = AEGetParamDesc(&myReply, keyAEResult, cQDRectangle, &pointdesc)) == noErr))
rect = **((Rect **)(pointdesc.dataHandle));
}
}
if (directdesc.dataHandle) AEDisposeDesc(&directdesc);
}
}
if (directdesc.dataHandle) AEDisposeDesc(&trshpropdesc);
}
if (directdesc.dataHandle) AEDisposeDesc(&propdesc);
}
if (directdesc.dataHandle) AEDisposeDesc(&myae);
}
if (directdesc.dataHandle) AEDisposeDesc(&targetaddress);
}
// Get Rect
*r = rect;
if (fiddlewithA5) SetA5(saveA5); // fix it up for crying out loud!
// if (usesystemmode) TurnSystemModeOff(); // we really DIDN'T want to do this
}
return(errnum); // the result
}